<template>
  <el-menu class="el-menu-vertical" :collapse="props.isCollapse" :default-active="defaultActive" :unique-opened="true"
    @select="handleSelect">
    <template v-for="(item) in menuData">
      <el-menu-item :index="item.path" class="menu-item" v-if="item.children?.length === 0">
        <BIcon :name="item.icon"></BIcon>
        <span>{{ item.name }}</span>
      </el-menu-item>

      <el-sub-menu :index="item.path" v-else>
        <template #title>
          <BIcon :name="item.icon"></BIcon>
          <span>{{ item.name }}</span>
        </template>
        <el-menu-item-group>
          <el-menu-item :index="subItem.path" v-for="(subItem) in item.children">　{{ subItem.name
            }}</el-menu-item>
        </el-menu-item-group>
      </el-sub-menu>
    </template>
  </el-menu>
</template>

<script setup lang="ts">
import { ref, watch } from "vue";
import BIcon from "./BIcon.vue";
import { useRouter, useRoute } from "vue-router";
// 获取路由实例
const router = useRouter();
const route = useRoute();
const getRoutes = router.getRoutes();
// 顶级路由
const topRoutes = computed(() =>
  getRoutes.filter((route) => route.meta.level == 1)
);
// 排序
topRoutes.value.sort((a: any, b: any) => a.meta.sort - b.meta.sort);

// 伸缩状态
let props = defineProps({
  isCollapse: {
    type: Boolean,
    default: false,
  },
});

/**
 * 获取子路由
 * @param children 子路由
 */
function getChildRoutes(children: any) {
  return children.map((item: any) => {
    return {
      path: `/${item.path}`,
      name: item.meta.title,
      icon: item.meta.icon,
    };
  });
}

interface MetaItem {
  title: string; // 标题名称
  sort: number; // 排序值
  icon: string; // 图标字符串
}

interface RouteItem {
  path: string; // 路径字符串
  name: string; // 名称字符串，通常是菜单或路由的标题
  icon?: string; // 图标字符串，可能为 undefined
  children?: RouteItem[]; // 子路由数组，可能为 undefined 或空数组
  meta: MetaItem
}

/**
 * 构建菜单数据结构
 */
let menuData = ref<RouteItem[]>([]);

/**
 * 遍历顶级路由数组，根据每个路由项构建菜单数据结构
 */
for (var i = 0; i < topRoutes.value.length; i++) {
  let item = topRoutes.value[i];
  let children: any = {};

  /**
   * 对首页进行特殊处理
   */
  if (item.path == "/") {
    children = {
      path: "/home",
      name: item.meta.title,
      icon: item.meta.icon,
      children: [],
    };
  } else {
    /**
     * 处理非首页的路由项，包括其子路由的获取
     */
    children = {
      path: item.path,
      name: item.meta.title,
      icon: item.meta.icon,
      children: item.children.length > 0 ? getChildRoutes(item.children) : [],
    };
  }

  /**
   * 将构建好的children对象推入menuData数组中
   */
  menuData.value.push(children);
}

/**
 * 处理路由路径以确定默认激活的菜单项
 *
 * @param {Object} route - 当前的路由对象，包含路径信息
 */
let routePath = route.path.split("/");

/**
 * 创建一个响应式的引用，用于保存默认激活的菜单项路径
 *
 * @type {Ref<string>} - 使用Vue的ref函数创建的响应式引用，其值为字符串类型
 * @value {string} - 默认激活的菜单项路径，格式为 '/{path}' 形式
 */
let defaultActive = ref<string>(`/${routePath[routePath.length - 1]}`);

// 监听路由路径的变化
watch(
  // 获取当前路由的路径
  () => route.path,
  // 当路由路径变化时执行的函数
  (newVal) => {
    // 将路由路径分割成数组
    let splitPath = newVal.split("/");
    // 设置默认激活的选项卡为最后一个路径段
    defaultActive.value = `/${splitPath[splitPath.length - 1]}`;
  }
);

// 路由跳转
const handleSelect = (_index: string, indexPath: Array<string>) => {
  let path = indexPath.join("");
  router.push(path);
};
</script>

<style lang="scss" scoped>
.el-menu-vertical {
  border-right: none;
}
</style>
